package ph.com.gs3.formalistics.model.communicators;

import java.util.Map;

import org.json.JSONException;
import org.json.JSONObject;

import ph.com.gs3.formalistics.global.utilities.logging.FLLogger;
import ph.com.gs3.formalistics.model.valueobjects.application.APIResponse;
import ph.com.gs3.formalistics.model.valueobjects.application.APIResponse.APIInvalidResponseException;

public abstract class HttpCommunicatorModule {

	public static final String TAG = HttpCommunicatorModule.class.getSimpleName();

	protected HttpCommunicator communicator;
	protected String server;

	public static final String SERVER_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";

	public enum ResultCode {
		SUCCESS, LOGIN_FAILED, APPLICATION_ERROR, INVALID_SERVER_RESPONSE, CONNECTION_FAILED
	}

	public HttpCommunicatorModule(HttpCommunicator communicator, String server) {
		this.communicator = communicator;
		setServer(server);
	}

	public HttpCommunicatorModule(HttpCommunicator communicator) {
		this.communicator = communicator;
	}

	// =====================================================================
	// Validators

	protected void commonValidation() throws CommunicatorException {

		if (server == null) {
			throw new CommunicatorException("Server not set");
		}

	}

	// =====================================================================
	// Getters and Setters

	protected APIResponse getResponse(String url, Map<String, String> requestParams)
	        throws CommunicatorException, APIInvalidResponseException {
		// throws CommunicatorException
		String rawResponseString = communicator.getResponseString(url, requestParams, "POST");

		// FLLogger.d(TAG, rawResponseString);

		JSONObject responseJSON;
		try {
			responseJSON = new JSONObject(rawResponseString);
		} catch (JSONException e) {

			APIInvalidResponseException convertedException = new APIInvalidResponseException(e);
			convertedException.setRawResponseString(rawResponseString);

			FLLogger.d(TAG, "Invalid response: " + rawResponseString);

			throw convertedException;
		}

		// throws APIResponseException
		return new APIResponse(responseJSON);
	}

	protected void setServer(String server) {

		if (server != null) {
			server = server.trim();
		} else {
			server = "";
		}

		// make sure that the server contains http
		if (!server.contains("http://") && !server.isEmpty()) {
			this.server = "http://" + server;
		} else {
			this.server = server;
		}
	}

	public String getServer() {
		return server;
	}

	public HttpCommunicator getCommunicator() {
		return this.communicator;
	}

	// =====================================================================
	// Exceptions

	public static class CommunicatorException extends Exception {

		private static final long serialVersionUID = -8118090139548825856L;

		public CommunicatorException(String message) {
			super(message);
		}

		public CommunicatorException(String message, Exception e) {
			super(message, e);
		}

	}

}
